package com.maxd.modules.redPacket.service.impl;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.maxd.error.Result;
import com.maxd.error.ResultUtil;
import com.maxd.model.CommonInfo;
import com.maxd.model.MessageInfo;
import com.maxd.model.TimedTask;
import com.maxd.model.UserInfo;
import com.maxd.modules.redPacket.dao.RedPacketDetailsJpaRepository;
import com.maxd.modules.redPacket.dao.RedPacketDetailsRepository;
import com.maxd.modules.redPacket.dao.RedPacketJpaRepository;
import com.maxd.modules.redPacket.dao.RedPacketRepository;
import com.maxd.modules.redPacket.entity.RedPacket;
import com.maxd.modules.redPacket.entity.RedPacketDetails;
import com.maxd.modules.redPacket.entity.Storeroom;
import com.maxd.modules.redPacket.service.IRedPacketService;
import com.maxd.modules.redPacket.service.IStoreroomService;
import com.maxd.modules.redPacket.utils.HelpTaskCodeUtil;
import com.maxd.modules.redPacket.utils.QrCodeUtil;
import com.maxd.respository.common.CommonRepository;
import com.maxd.respository.timedTask.TimedTaskJpaRepository;
import com.maxd.respository.userinfo.UserRepository;
import com.maxd.service.article.ArticleBrowsingHistoryService;
import com.maxd.service.message.IMessageService;
import com.maxd.service.money.IMoneyDetailsService;
import com.maxd.service.userinfo.IUserService;
import com.maxd.utils.AmountCalUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 *  红包
 */
@Service
public class RedPacketServiceImpl implements IRedPacketService {

    @Autowired
    private RedPacketRepository redPacketRepository;
    @Autowired
    private RedPacketJpaRepository redPacketJpaRepository;
    @Autowired
    private CommonRepository commonRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RedPacketDetailsJpaRepository redPacketDetailsJpaRepository;
    @Autowired
    private IUserService userService;
    @Autowired
    private IMessageService iMessageService;
    @Autowired
    private IStoreroomService storeroomService;
    @Autowired
    private IMoneyDetailsService iMoneyDetailsService;
    /** 定时任务 */
    @Autowired
    private TimedTaskJpaRepository timedTaskJpaRepository;
    @Autowired
    private RedPacketDetailsRepository redPacketDetailsRepository;

    @Override
    public Result withdrawDeposit(Long redPacketId){
        RedPacket redPacket = redPacketJpaRepository.findById(redPacketId).orElse(null);
        if(redPacket!=null && redPacket.getStatus().equals(1)){
            return ResultUtil.error(-1,"红包金额未达到，继续邀请好友来赚赏金吧！");
        }else if(redPacket!=null && redPacket.getStatus().equals(3)){
            return ResultUtil.error(-1,"红包已经提现了，请去【我的】-【可提现金额】中查看！");
        }
        if(redPacket!=null && redPacket.getStatus().equals(2)){
            redPacket.setStatus(3);
            redPacketJpaRepository.save(redPacket);
            userRepository.updateJiFenAdd(String.valueOf(redPacket.getTarGetMoney()),redPacket.getUserId());
            iMoneyDetailsService.saveBody(redPacket.getUserId(), 1, 4,  "红包到账", "红包提现成功，已经到余额了",redPacket.getTarGetMoney());
            return ResultUtil.successMsg("提现成功，请去【我的】-【可提现金额】中查看");
        }
        return ResultUtil.error(-1,"红包金额未达到，继续邀请好友来赚赏金吧！");
    }




    @Override
    public RedPacket insertRedPacket(Long userId){
        RedPacket redPacket1 = redPacketRepository.selectRedPacketByUserIdAndStatus(userId);
        if(redPacket1!=null){
            return redPacket1;
        }
        List<RedPacket> redPacketCountByUserId = redPacketRepository.selectRedPacketCountByUserId(userId);
        if(redPacketCountByUserId!=null && redPacketCountByUserId.size()>0){
            if(redPacketCountByUserId.size()==1){
                return redPacketCountByUserId.get(0);
            }else{
                for(int i=0;i<redPacketCountByUserId.size()-1;i++){
                    redPacketJpaRepository.deleteById(redPacketCountByUserId.get(i).getRedPacketId());
                }
                RedPacket redPacket = redPacketRepository.selectRedPacketCountByUserIds(userId);
                if(redPacket!=null){
                    return redPacket;
                }
            }

        }
        RedPacket redPacket=new RedPacket();
        redPacket.setUserId(userId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //红包金额
        CommonInfo one = commonRepository.findOne(110);
        redPacket.setTarGetMoney(Double.parseDouble(one.getValue()));
        //红包期限
        CommonInfo one1 = commonRepository.findOne(111);
        int day = Integer.parseInt(one1.getValue());
        Calendar cal = Calendar.getInstance();
        redPacket.setCreateTime(sdf.format(cal.getTime()));
        cal.add(Calendar.DAY_OF_MONTH, day);
        redPacket.setEndTime(sdf.format(cal.getTime()));
        //所需人数
        CommonInfo one2 = commonRepository.findOne(112);
        redPacket.setTarGetNumPeople(Integer.parseInt(one2.getValue()));
        //根据当前人数进行计算  目前的金额
        Double tarGetMoney = redPacket.getTarGetMoney();
        Double mul = AmountCalUtils.mul(tarGetMoney, 100);
        Double sub = AmountCalUtils.sub(mul, redPacket.getTarGetNumPeople());
        sub = AmountCalUtils.divide(sub, 100);
        //现在生成的金额是剩下的人数每人一分钱  再扣除百分之5-3 将每个人的金额随机
        int suiji = new Random().nextInt(5)%(5-3+1) + 3;
        Double dou=Double.parseDouble(suiji+"")/100;
        Double mul1 = AmountCalUtils.mul(tarGetMoney, dou);
        mul1=AmountCalUtils.sub(sub,mul1);
        redPacket.setMoney(mul1);
        redPacket.setStatus(1);
        redPacket.setNumPeople(0);
        RedPacket save = redPacketJpaRepository.save(redPacket);
        //添加砍价记录
        RedPacketDetails redPacketDetails=new RedPacketDetails();
        redPacketDetails.setCreateTime(sdf.format(new Date()));
        redPacketDetails.setRedPacketId(redPacket.getRedPacketId());
        redPacketDetails.setUserId(redPacket.getUserId());
        redPacketDetails.setMoney(mul1);
        redPacketDetails.setStatus(2);
        redPacketDetailsJpaRepository.save(redPacketDetails);
        String s = HelpTaskCodeUtil.toSerialCode(save.getRedPacketId());
        save.setCode(s);
        save = redPacketJpaRepository.save(redPacket);
        //添加定时任务
        TimedTask timedTask=new TimedTask();
        timedTask.setType(4);
        timedTask.setObjectId(save.getRedPacketId());
        timedTask.setTitle("红包助力过期定时");
        timedTask.setCreateTime(new Date());
        timedTask.setEndTime(cal.getTime());
        timedTaskJpaRepository.save(timedTask);
        save.setStatus(0);
        return save;
    }



    @Override
    public Result helpTakeRedPacket(Long userId,String code){
        UserInfo userById = userRepository.getUserById(userId);
        if(userById==null){
            return ResultUtil.error(-1,"用户未登录，请先登陆！");
        }
        if(StringUtils.isNotEmpty(code)) {
            long id = HelpTaskCodeUtil.serialCodeToId(code);
            RedPacket redPacket = redPacketJpaRepository.findById(id).orElse(null);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (redPacket != null) {
                //判断当前用户是否助力过
                int i = redPacketDetailsRepository.selectRedPacketDetailsByUserIdAndRedPackId(userById.getId(), redPacket.getRedPacketId());
                if (i == 0) {
                    //判断当前用户今日助力次数
                    int i1 = redPacketDetailsRepository.selectRedPacketDetailsByUserIdAndDate(userById.getId());
                    CommonInfo one = commonRepository.findOne(113);
                    Integer value = Integer.parseInt(one.getValue());
                    if (i1 < value) {
                        RedPacketDetails redPacketDetails = new RedPacketDetails();
                        redPacketDetails.setCreateTime(sdf.format(new Date()));
                        redPacketDetails.setRedPacketId(redPacket.getRedPacketId());
                        redPacketDetails.setUserId(userById.getId());
                        redPacketDetails.setStatus(1);
                        redPacketDetails.setMoney(0.00);
                        redPacketDetailsJpaRepository.save(redPacketDetails);
                    }
                }
            }
        }
        return ResultUtil.success(insertRedPacket(userId));
    }

    @Override
    public void confirm(Long userId){
        if(userId!=null && userId!=0){
            List<RedPacketDetails> redPacketDetailsList = redPacketDetailsRepository.selectRedPacketDetailsListByUserId(userId);
            if(redPacketDetailsList.size()>0){

            }
            for(RedPacketDetails redPacketDetails:redPacketDetailsList){
                RedPacket redPacket = redPacketJpaRepository.findById(redPacketDetails.getRedPacketId()).orElse(null);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                if(redPacket!=null && redPacket.getStatus()==1){
                    //获取目标人数
                    Integer tarGetNumPeople = redPacket.getTarGetNumPeople();
                    //当前目标金额
                    Double tarGetMoney = redPacket.getTarGetMoney();
                    //当前助力金额
                    Double money = redPacket.getMoney();
                    //当前助力人数
                    Integer numPeople = redPacket.getNumPeople();
                    //缺少人数
                    Integer num=tarGetNumPeople-numPeople;
                    //待赠送金额
                    Double sub = AmountCalUtils.sub(tarGetMoney, money);
                    redPacketDetails.setStatus(2);
                    if(num==1){
                        redPacket.setStatus(2);
                        redPacketJpaRepository.save(redPacket);
                        //剩余助力人数为1
                        redPacketRepository.updateRedPacketTarGetMoneyAdd(sub,redPacket.getRedPacketId());
                        //添加砍价记录
                        redPacketDetails.setMoney(sub);
                        redPacketDetailsJpaRepository.save(redPacketDetails);
                        //红包到账发送消息提醒红包已到账 去提现
                        UserInfo userByPhone=userRepository.getUserById(redPacket.getUserId());
                        if (userByPhone.getClientid() != null) {
                            userService.pushToSingle("红包到账了！", "您的红包已经到账了，赶快去提现吧！", userByPhone.getClientid());
                        }
                        MessageInfo messageInfo = new MessageInfo();
                        messageInfo.setContent("您的红包已经到账了，赶快去提现吧！");
                        messageInfo.setTitle("红包到账了！");
                        messageInfo.setState(String.valueOf(8));
                        messageInfo.setUserName(userByPhone.getNickName());
                        messageInfo.setUserId(String.valueOf(userByPhone.getId()));
                        messageInfo.setCreateAt(sdf.format(new Date()));
                        iMessageService.saveBody(messageInfo);
                    }else if(num>0){
                        //待助力人数大于1则按照剩余金额进行随机赠送
                        //根据当前人数进行计算  目前的金额
                        Double mul = AmountCalUtils.mul(sub, 100);
                        Double sub1 = AmountCalUtils.sub(mul, num);
                        Double aDouble = AmountCalUtils.divide(sub1, 100);
                        if(aDouble>0){
                            //每人一分钱 还有多余的钱 按照随机赠送
                            int suiji = new Random().nextInt(100)%(100-1+1) + 1;
                            Double dou=Double.parseDouble(suiji+"")/100;
                            Double mul1 = AmountCalUtils.mul(aDouble, dou);
                            double add = AmountCalUtils.add(mul1, 0.01);
                            redPacketRepository.updateRedPacketTarGetMoneyAdd(add,redPacket.getRedPacketId());
                            //添加砍价记录
                            redPacketDetails.setMoney(add);
                            redPacketDetailsJpaRepository.save(redPacketDetails);
                        }else if(aDouble==0){
                            //每人正好一分钱 砍价一分钱
                            redPacketRepository.updateRedPacketTarGetMoneyAdd(0.01,redPacket.getRedPacketId());
                            //添加砍价记录
                            redPacketDetails.setMoney(0.01);
                            redPacketDetailsJpaRepository.save(redPacketDetails);
                        }else{
                            //钱不足一分钱 随机砍价  可能成功可能失败
                            int suiji = new Random().nextInt(2)%(2-1+1) + 1;
                            if (sub==0) {
                                suiji=0;
                            }
                            if(suiji==1){
                                //砍价成功 砍价一分钱
                                redPacketRepository.updateRedPacketTarGetMoneyAdd(0.01,redPacket.getRedPacketId());
                                //添加砍价记录
                                redPacketDetails.setMoney(0.01);
                                redPacketDetailsJpaRepository.save(redPacketDetails);
                            }else{
                                //砍价失败  增加人数  不增加金额
                                redPacketRepository.updateRedPacketTarGetMoneyAdd(0.00,redPacket.getRedPacketId());
                                //添加砍价记录
                                redPacketDetails.setMoney(0.00);
                                redPacketDetailsJpaRepository.save(redPacketDetails);
                            }
                        }
                    }
                }else{
                    redPacketDetails.setStatus(3);
                    redPacketDetailsJpaRepository.save(redPacketDetails);
                }
            }
        }

    }





    @Override
    public Result getDayMoney(){
        return ResultUtil.success(redPacketRepository.getDayMoney());
    }


    @Override
    public void getLinkQrCode(Long redPacketId,HttpServletResponse response){
        RedPacket redPacket = redPacketJpaRepository.findById(redPacketId).orElse(null);
        if(redPacket!=null) {
            int size = 0, suiji = 0;
            //获取链接 的总数
            List<Storeroom> linkList = storeroomService.selectStoreroomListByClassify(2);
            size = linkList.size();
            suiji = new Random().nextInt(size) % (size + 1) + 1;
            suiji = suiji - 1;
            String link = linkList.get(suiji).getContent();
            StringBuilder sb = new StringBuilder(link);
            sb.append("/pages/index/openRedEnvelope");//拼接页面路径
            sb.append("?code=");
            sb.append(redPacket.getCode());
            sb.append("&invitation=");
            UserInfo userById = userRepository.getUserById(redPacket.getUserId());
            sb.append(userById.getInvitationCode());
            Map<EncodeHintType, String> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            try {
                //
                BitMatrix bitMatrix = new MultiFormatWriter().encode(sb.toString(), BarcodeFormat.QR_CODE, 400, 400, hints);
                BufferedImage bufferedImage = QrCodeUtil.toBufferedImage(bitMatrix);
                ImageIO.write(bufferedImage, "JPG", response.getOutputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    @Override
    public Result getLink(Long redPacketId){
        RedPacket redPacket = redPacketJpaRepository.findById(redPacketId).orElse(null);
        if(redPacket!=null){
            //获取文案 的总数
            List<Storeroom> contentList = storeroomService.selectStoreroomListByClassify(1);
            int size = contentList.size();
            int suiji = new Random().nextInt(size)%(size+1) + 1;
            suiji=suiji-1;
            String content = contentList.get(suiji).getContent();
            //获取链接 的总数
            List<Storeroom> linkList = storeroomService.selectStoreroomListByClassify(2);
            size = linkList.size();
            suiji = new Random().nextInt(size)%(size+1) + 1;
            suiji=suiji-1;
            String link = linkList.get(suiji).getContent();
            //随机生成文案和链接  拼接后返回前端
            StringBuilder sb=new StringBuilder(content+"\n\n");
            sb.append(link);
            sb.append("/pages/index/openRedEnvelope");//拼接页面路径
            sb.append("?code=");
            sb.append(redPacket.getCode());
            sb.append("&invitation=");
            UserInfo userById = userRepository.getUserById(redPacket.getUserId());
            sb.append(userById.getInvitationCode());
            return ResultUtil.success(sb.toString());

        }
        return ResultUtil.error(-1,"红包过期或已砍价成功！");
    }

    @Override
    public Result selectRedPacketListByUserId(Integer page,Integer size,Long userId){
        Pageable pageable = PageRequest.of(page, size);
        Page<Map<String, Object>> maps = redPacketRepository.selectRedPacketListByUserIds(pageable, userId);
        List<Map<String, Object>> content = maps.getContent();
        List<String> list=new ArrayList<>();
        for(Map<String,Object> map:content){
            String nickName = String.valueOf(map.get("nickName"));
            String phone = String.valueOf(map.get("phone"));
            if(StringUtils.isEmpty(nickName)){
                nickName=phone;
            }
            nickName = nickName.replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})","$1****$2");
            list.add(nickName);
        }
        Map<String,Object> map=new HashMap<>();
        map.put("data",maps);
        map.put("list",list);
        return ResultUtil.success(map);
    }

    @Override
    public Result selectRedPacketListByUserIds(Integer page,Integer size,Long userId,Integer status){
        Pageable pageable = PageRequest.of(page, size);
        Page<RedPacket> redPackets;
        if(status==0){
            redPackets = redPacketRepository.selectRedPacketListByUserIdV1(pageable,userId);
        }else{
            redPackets=redPacketRepository.selectRedPacketListByUserId(pageable,userId,status);
        }
        for(RedPacket redPacket:redPackets){
            UserInfo userById = userRepository.getUserById(redPacket.getUserId());
            if(userById!=null){
                redPacket.setNickName(userById.getNickName());
            }
        }
        return ResultUtil.success(redPackets);
    }


    @Override
    public Result selectRedPacketListByStatus(Integer page,Integer size){
        Pageable pageable = PageRequest.of(page, size);
        Page<Map<String, Object>> maps = redPacketRepository.selectRedPacketListByStatus(pageable);
        List<Map<String, Object>> content = maps.getContent();
        List<String> list=new ArrayList<>();
        for(Map<String,Object> map:content){
            String nickName = String.valueOf(map.get("nickName"));
            String phone = String.valueOf(map.get("phone"));
            if(StringUtils.isEmpty(nickName)){
                nickName=phone;
            }
            nickName = nickName.replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})","$1****$2");
            list.add(nickName);
        }
        Map<String,Object> map=new HashMap<>();
        map.put("data",maps);
        map.put("list",list);
        return ResultUtil.success(map);
    }

    @Override
    public Result selectRedPacketListByStatuss(Integer page,Integer size,Integer status){
        Pageable pageable = PageRequest.of(page, size);
        Page<RedPacket> redPackets;
        if(status==0){
            redPackets = redPacketRepository.selectRedPacketList(pageable);
        }else{
            redPackets=redPacketRepository.selectRedPacketListByStatuss(pageable,status);
        }
        for(RedPacket redPacket:redPackets){
            UserInfo userById = userRepository.getUserById(redPacket.getUserId());
            if(userById!=null){
                redPacket.setNickName(userById.getNickName());
            }
        }
        return ResultUtil.success(redPackets);
    }


}
